import {Interceptor, InterceptorType} from "./Interceptor";
import {TsReflect} from "../util/TsReflect";
import {Action} from "./Action";
import {_, TsBase} from "../util/UtilTs";
import {Cons, JSCons} from "./EasyACons";

export class Controller extends TsBase{

    autoRegister  = true; //自动注册
    routePath = null; //父路径， action 的route 会追加到这个后面
    viewPath = '/'; //默认视图路径
    name:string = Cons.never;

    interceptors:Array<Interceptor> = [];//控制器级别 拦截器

    private tempActionProps = {}; //临时存放用


    constructor(){
        super();

        this.__init();
        //修正路径
        if(!this.routePath){
            this.routePath = Controller.getFixedRoutePath(this);
        }
        this.name = this[JSCons.sConstructor].name;

        //把方法从普通方法转换成 Action的实例, 并且重新整理
        this.createActionsAndClean();
   }


    cleanupInters(){
       this.interceptors = Controller.reorganizeInterceptor(this.interceptors) as Array<Interceptor>;

    };

    createActionsAndClean(){
        const self = this;
        _.each(TsReflect.getFuncProtoMethods(self),(m,name)=>self[name] = Action.create(name, m) );

        const tempActionProps = _.get(self,`tempActionProps`,{});
        const actions = self.getActions();
        _.each(actions,(action:Action)=>{

            action.interceptors = _.concat(self.interceptors, _.get(tempActionProps,`${action.name}.interceptors`,[]));
            action.controller = self;

            _.merge(action, _.get(tempActionProps,`${action.name}.props`,{}));
        });

        delete self.tempActionProps;

    }


    //获取actions
    getActions():{[key: string]: Action}{
        let actions:{ [key: string]: Action} = {};
        for(let k in this){
            let ac:Action = <any>this[k];
            if(ac instanceof Action){
                actions[ac.name] = ac;
            }
        }
        return actions;
    }

    getAction(name:string):Action{
        return this[name];
    }


    // DClazz  子类 或者孙子类   UClazz  父类或者更
    static isControllerDClazz=(clazz)=>TsReflect.isExtendsFromClazz(clazz,Controller);

    //获取 controller 有效名
    static getFixedRoutePath(instance){
        let name = TsReflect.getClass(instance).name;
        return name.indexOf(Cons.Controller) > 0 ? name.substring(0, name.indexOf(Cons.Controller)) : name.toString();
    }

    //根据清除规则，整理拦截器
    static reorganizeInterceptor(handles:Array<Interceptor>): Array<Interceptor> {
        let ret = [];
        handles = _.filter(handles, _.negate(_.isNil));
        _.each(handles, (handle) => {
            if (handle.type === InterceptorType.flow) {
                ret.push(handle);
            }
            else {
                _.pullAllBy(ret, [handle], (item) => {
                    return TsReflect.getClass(item) === TsReflect.getClass(handle);
                });
            }
        });
        return ret;
    }




}

export function ControllerBind(props: Partial<Controller>) {
    return function <T extends Controller, U extends { new():T }>(clazz: U) {
        const self:typeof Controller = clazz as any;
        self.__init((ins)=>{
            TsReflect.setProps(ins,props);
        });
        return clazz;
    };
}











